package main

import (
	"fmt"
	"reflect"
)

/*
*
type StructField struct {
// 参见 http://golang.org/ref/spec#Uniqueness_of_identifiers
Name string // Name 是字段的名字
PkgPath string //PkgPath 是非导出字段的包路径，对导出字段该字段为"" Type Type // 字段的类型
Tag StructTag // 字段的标签
Offset uintptr // 字段在结构体中的字节偏移量
Index []int // 用于 Type.FieldByIndex 时的索引切片
Anonymous bool // 是否匿名字段
}
*/
//student 结构体
type Student struct {
	Name  string `json:"name"`
	Age   int    `json:"age"`
	Score int    `json:"score"`
}

func (s Student) GetInfo() string {
	var str = fmt.Sprintf("姓名:%v 年龄:%v 成绩:%v", s.Name, s.Age, s.Score)
	fmt.Println(str)
	return str
}

func (s *Student) SetInfo(name string, age int, score int) {
	s.Name = name
	s.Age = age
	s.Score = score
}

func (s *Student) Print() {
	fmt.Println("打印方法...")
}

// 打印字段
func PrintStructField(s interface{}) {
	t := reflect.TypeOf(s)
	if t.Kind() != reflect.Struct && t.Elem().Kind() != reflect.Struct {
		fmt.Println("传入的不是结构体")
		return
	}
	//1、通过类型变量里面的 Field 可以获取结构体的字段
	field0 := t.Field(0)
	fmt.Println(field0.Name)            // Name
	fmt.Println(field0.Type)            // string
	fmt.Println(field0.Tag.Get("json")) // name
	//2、通过类型变量里面的 FieldByName 可以获取结构体的字段
	field1, _ := t.FieldByName("Age")
	fmt.Println(field1.Name)            // Age
	fmt.Println(field1.Type)            // int
	fmt.Println(field1.Tag.Get("json")) // age
	//3、获取到该结构体有几个字段
	num := t.NumField()
	fmt.Println("字段数量:", num) // 3
}
func main() {

	var s Student = Student{
		"xiaosan",
		18,
		88,
	}

	PrintStructField(s)

	fmt.Println("------------------------")
	PrintStructField(&s)
	//PrintStudentInfo("a")

	fmt.Println(s)

}
